/*
 * Copyright (C) 2013, Pavel Samko <bulldozerbsg@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the "Pavel Samko" nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

#pragma once
#ifndef PLUG_FUNCS_H
#define PLUG_FUNCS_H

// WCX
#define OPENARCHIVE 1
#define READHEADER 2
#define PROCESSFILE 3
#define CLOSEARCHIVE 4
#define SETCHANGEVOLPROC 5
#define CHANGEVOLPROC 6
#define SETPROCESSDATAPROC 7
#define PROCESSDATAPROC 8
#define PACKFILES 9
#define DELETEFILES 10
#define GETPACKERCAPS 11
#define CONFIGUREPACKER 12
#define STARTMEMPACK 13
#define PACKTOMEM 14
#define DONEMEMPACK 15
#define CANYOUHANDLETHISFILE 16
#define PACKSETDEFAULTPARAMS 17
#define PKSETCRYPTCALLBACK 18
#define PKCRYPTPROC 19
#define READHEADEREX 20
#define GETBACKGROUNDFLAGS 21
#define OPENARCHIVEW 22
#define READHEADEREXW 23
#define PROCESSFILEW 24
#define SETCHANGEVOLPROCW 25
#define CHANGEVOLPROCW 26
#define SETPROCESSDATAPROCW 27
#define PROCESSDATAPROCW 28
#define PACKFILESW 29
#define DELETEFILESW 30
#define STARTMEMPACKW 31
#define CANYOUHANDLETHISFILEW 32
#define PKSETCRYPTCALLBACKW 33
#define PKCRYPTPROCW 34

// call type
#define CALL_ERROR 0
#define CALL_QUERY 1
#define CALL_ANSWER 2

// serialize
#define SET_FUNC(p, funcNum) \
	*((uint8_t *)p) = (uint8_t)funcNum; \
	p += sizeof(uint8_t);
#define SET_CALLTYPE(p, callType) \
	*((uint8_t *)p) = (uint8_t)callType; \
	p += sizeof(uint8_t);
#define SET_HANDLE(p, handle) \
	*((uint32_t *)p) = (uint32_t)handle; \
	p += sizeof(uint32_t);
#define SET_INT(p, i) \
	*((int32_t *)p) = (int32_t)i; \
	p += sizeof(int32_t);
#define SET_UINT(p, i) \
	*((uint32_t *)p) = (uint32_t)i; \
	p += sizeof(uint32_t);
#define SET_BOOL(p, b) \
	*((int32_t *)p) = (int32_t)b; \
	p += sizeof(int32_t);
#define SET_DWORD(p, d) \
	*((uint32_t *)p) = (uint32_t)d; \
	p += sizeof(uint32_t);
#define SET_BUFF(p, b, bSize) \
	if (b && bSize) \
	{ \
		*((uint8_t *)p) = 1; \
		p += sizeof(uint8_t); \
		*((uint32_t *)p) = bSize; \
		p += sizeof(uint32_t); \
		memcpy(p, b, bSize); \
		p += bSize; \
	} else \
	{ \
		*((uint8_t *)p) = 0; \
		p += sizeof(uint8_t); \
	}
#define SET_STR_A(p, s) \
	if (s) \
	{ \
		*((uint8_t *)p) = 1; \
		p += sizeof(uint8_t); \
		size_t sSize = strlen(s) + 1; \
		*((uint32_t *)p) = sSize; \
		p += sizeof(uint32_t); \
		memcpy(p, s, sSize); \
		p += sSize * sizeof(char); \
	} else \
	{ \
		*((uint8_t *)p) = 0; \
		p += sizeof(uint8_t); \
	}
#define SET_STR_W(p, s) \
	if (s) \
	{ \
		*((uint8_t *)p) = 1; \
		p += sizeof(uint8_t); \
		size_t sSize = wcslen(s) + 1; \
		*((uint32_t *)p) = sSize; \
		p += sizeof(uint32_t); \
		wmemcpy((wchar_t *)p, s, sSize); \
		p += sSize * sizeof(wchar_t); \
	} else \
	{ \
		*((uint8_t *)p) = 0; \
		p += sizeof(uint8_t); \
	}
#define SET_STRLIST_A(p, l) \
	if (l) \
	{ \
		*((uint8_t *)p) = 1; \
		p += sizeof(uint8_t); \
		size_t sSize = strlistlen(l) + 1; \
		*((uint32_t *)p) = sSize; \
		p += sizeof(uint32_t); \
		memcpy(p, l, sSize); \
		p += sSize * sizeof(char); \
	} else \
	{ \
		*((uint8_t *)p) = 0; \
		p += sizeof(uint8_t); \
	}
#define SET_STRLIST_W(p, l) \
	if (l) \
	{ \
		*((uint8_t *)p) = 1; \
		p += sizeof(uint8_t); \
		size_t sSize = wcslistlen(l) + 1; \
		*((uint32_t *)p) = sSize; \
		p += sizeof(uint32_t); \
		wmemcpy((wchar_t *)p, l, sSize); \
		p += sSize * sizeof(wchar_t); \
	} else \
	{ \
		*((uint8_t *)p) = 0; \
		p += sizeof(uint8_t); \
	}

// deserialize
#define GET_FUNC(p, funcNum) \
	funcNum = (uint8_t)(*((uint8_t *)p)); \
	p += sizeof(uint8_t);
#define GET_CALLTYPE(p, callType) \
	callType = (uint8_t)(*((uint8_t *)p)); \
	p += sizeof(uint8_t);
#define GET_HANDLE(p, handle) \
	handle = (HANDLE)(*((uint32_t *)p)); \
	p += sizeof(uint32_t);
#define GET_INT(p, i) \
	i = (int)(*((int32_t *)p)); \
	p += sizeof(int32_t);
#define GET_UINT(p, i) \
	i = (unsigned int)(*((uint32_t *)p)); \
	p += sizeof(uint32_t);
#define GET_BOOL(p, b) \
	b = (BOOL)(*((int32_t *)p)); \
	p += sizeof(int32_t);
#define GET_DWORD(p, d) \
	d = (DWORD)(*((uint32_t *)p)); \
	p += sizeof(uint32_t);
#define GET_BUFF(p, b, bSize) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			bSize = (int)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			b = (char *)p; \
			p += bSize; \
		} else \
		{ \
			b = NULL; \
			bSize = 0; \
		} \
	}
#define GET_BUFF2(p, b) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			size_t bSize = (int)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			memcpy(b, p, bSize); \
			p += bSize; \
		} else \
		{ \
			b = NULL; \
		} \
	}
#define GET_STR_A(p, s) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			uint32_t sSize = (uint32_t)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			s = (char *)p; \
			p += sSize; \
		} else \
		{ \
			s = NULL; \
		} \
	}
#define GET_STR_W(p, s) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			uint32_t sSize = (uint32_t)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			s = (wchar_t *)p; \
			p += sSize; \
		} else \
		{ \
			s = NULL; \
		} \
	}
#define GET_STRLIST_A(p, l) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			uint32_t sSize = (uint32_t)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			l = (char *)p; \
			p += sSize; \
		} else \
		{ \
			l = NULL; \
		} \
	}
#define GET_STRLIST_W(p, l) \
	{ \
		uint8_t n = (uint8_t)(*((uint8_t *)p)); \
		p += sizeof(uint8_t); \
		if (n) \
		{ \
			uint32_t sSize = (uint32_t)(*((uint32_t *)p)); \
			p += sizeof(uint32_t); \
			l = (wchar_t *)p; \
			p += sSize; \
		} else \
		{ \
			l = NULL; \
		} \
	}

#endif // PLUG_FUNCS_H
